package com.titanrise.crm.common.utils;

import com.github.freva.asciitable.AsciiTable;
import com.titanrise.crm.common.enums.LogEffect;
import com.titanrise.crm.environment.annotation.ColumnName;

import java.util.Arrays;
import java.util.function.Supplier;

import java.lang.reflect.Field;
import java.util.List;

public class Console {
    public static void println(String message, LogEffect... effects) {
        StringBuilder sb = new StringBuilder();
        for (LogEffect effect : effects)
            sb.append(effect.toString());
        System.out.println(sb + message + LogEffect.RESET);
    }

    public static void print(String message, LogEffect... effects) {
        StringBuilder sb = new StringBuilder();
        for (LogEffect effect : effects)
            sb.append(effect.toString());
        System.out.print(sb + message + LogEffect.RESET);
    }

    public static Supplier<Nothing> putStrLn(String message, LogEffect... effects) {
        return Nothing.ofRunnable(() -> println(message, effects));
    }

    public static Supplier<Nothing> putStr(String message, LogEffect... effects) {
        return Nothing.ofRunnable(() -> print(message, effects));
    }

    public static <T> void showTable(List<T> list) {
        if (list == null || list.isEmpty())
            throw new RuntimeException("List is null or empty");

        Class<?> clazz = list.get(0).getClass();
        Field[] fields = clazz.getDeclaredFields();
        String table = AsciiTable.getTable(
                Arrays.stream(clazz.getDeclaredFields())
                        .map(field -> field.isAnnotationPresent(ColumnName.class)
                                ? field.getAnnotation(ColumnName.class).value()
                                : field.getName())
                        .toArray(String[]::new),
                list.stream()
                        .map(e -> Arrays.stream(fields)
                                .map(field -> {
                                    field.setAccessible(true);
                                    try {
                                        Object value = field.get(e);
                                        return value == null || value.equals("null") ? "NULL" : value.toString();
                                    } catch (IllegalAccessException ex) {
                                        throw new RuntimeException(ex);
                                    }
                                })
                                .toArray(String[]::new)
                        )
                        .toArray(String[][]::new)
        );

        System.out.println(table);
    }

}
